home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / dos6mm.zip / FILEMON.ASM < prev    next >
Assembly Source File  |  1993-03-31  |  18KB  |  392 lines

  1. ;****************************************************************************
  2. ; FILEMON monitors the system file table as an aid in determining the
  3. ; optimal setting for FILES= in CONFIG.SYS. Its syntax is:
  4. ;
  5. ;       FILEMON
  6. ;
  7. ; The first time it's run, FILEMON becomes memory-resident so it can track
  8. ; file activity in the background. Each time thereafter, it reports the
  9. ; number of files that are currently open and the maximum that were open
  10. ; at any time since monitoring was begun.
  11. ;****************************************************************************
  12.  
  13. code            segment
  14.                 assume  cs:code
  15.                 org     100h
  16. begin:          jmp     init
  17.  
  18. signature       db      0,1,2,"FILEMON",2,1,0   ;Program signature
  19. prog_id         db      ?                       ;Multiplex ID number
  20. int21h          dd      ?                       ;Interrupt 21h vector
  21. int2Fh          dd      ?                       ;Interrupt 2FH vector
  22. maxfiles        db      0                       ;Maximum file open count
  23. lol             dd      ?                       ;List of Lists address
  24.  
  25. ;****************************************************************************
  26. ; DOS_INT handles calls to interrupt 21h.
  27. ;****************************************************************************
  28.  
  29. dos_int         proc    far
  30.                 pushf                           ;Save FLAGS
  31.                 cmp     ah,3Ch                  ;Create file?
  32.                 je      dosint1
  33.                 cmp     ah,3Dh                  ;Open file?
  34.                 je      dosint1
  35.                 cmp     ah,45h                  ;Duplicate handle?
  36.                 je      dosint1
  37.                 cmp     ah,46h                  ;Force duplicate handle?
  38.                 je      dosint1
  39.                 cmp     ah,5Ah                  ;Create temporary file?
  40.                 je      dosint1
  41.                 cmp     ah,5Bh                  ;Create new file?
  42.                 je      dosint1
  43.                 cmp     ah,6Ch                  ;Extended open/create?
  44.                 je      dosint1
  45.                 popf                            ;Restore FLAGS
  46.                 jmp     cs:[int21h]             ;Jump to DOS
  47. ;
  48. ; Place the call to DOS, then count the number of open files upon return.
  49. ;
  50. dosint1:        popf                            ;Restore FLAGS and call DOS
  51.                 pushf
  52.                 call    cs:[int21h]
  53.  
  54.                 pushf                           ;Save registers
  55.                 push    ax
  56.                 push    cx
  57.                 push    si
  58.                 push    di
  59.                 push    es
  60.  
  61.                 sti                             ;Interrupts on
  62.                 call    count_files             ;Count open files
  63.                 cmp     al,cs:[maxfiles]        ;Record result if count
  64.                 jbe     dosint2                 ;exceeds current maximum
  65.                 mov     cs:[maxfiles],al
  66.  
  67. dosint2:        pop     es                      ;Restore registers
  68.                 pop     di
  69.                 pop     si
  70.                 pop     cx
  71.                 pop     ax
  72.                 popf
  73.                 sti                             ;Enable interrupts
  74.                 ret     2                       ;Exit with FLAGS intact
  75. dos_int         endp
  76.  
  77. ;****************************************************************************
  78. ; MPLEX_INT handles interrupt 2FH. If, on entry, AH is set to INSTALL's
  79. ; multiplex ID number, MPLEX_INT uses the value in AL as a function code.
  80. ; The functions supported are:
  81. ;
  82. ;    00H    Returns FFH in AL to indicate the program is installed
  83. ;           and returns the address of its signature in ES:DI.
  84. ;
  85. ;    01H    Returns the number of files currently open in AL and the
  86. ;           maximum number of files open concurrently in AH.
  87. ;****************************************************************************
  88.  
  89. mplex_int       proc    far
  90.                 pushf                           ;Save FLAGS register
  91.                 cmp     ah,cs:[prog_id]         ;Branch if AH holds the
  92.                 je      mplex2                  ;multiplex ID
  93.                 popf                            ;Restore FLAGS
  94.                 jmp     cs:[int2Fh]             ;Pass the interrupt on
  95. ;
  96. ; Function 00H verifies that the program is installed.
  97. ;             
  98. mplex2:         popf                            ;Restore FLAGS
  99.                 or      al,al                   ;Branch if function code
  100.                 jnz     mplex3                  ;is other than 00h
  101.                 mov     al,0FFh                 ;Set AL to FFh
  102.                 push    cs                      ;Point ES:DI to the program
  103.                 pop     es                      ;signature
  104.                 mov     di,offset signature
  105. ;
  106. ; Function 01H returns the number of open files (current and maximum).
  107. ;
  108. mplex3:         cmp     al,1                    ;Exit if function code
  109.                 jne     mplex5                  ;is other than 01h
  110.                 call    count_files             ;Count open files
  111.                 cmp     al,cs:[maxfiles]        ;Record result if count
  112.                 jbe     mplex4                  ;exceeds current maximum
  113.                 mov     cs:[maxfiles],al
  114. mplex4:         mov     ah,cs:[maxfiles]        ;Load AH with maximum count
  115. mplex5:         iret                            ;Return from interrupt
  116. mplex_int       endp
  117.  
  118. ;****************************************************************************
  119. ; COUNT_FILES returns in AL the number of files that are currently open.
  120. ;****************************************************************************
  121.  
  122. count_files     proc    near
  123.                 les     di,cs:[lol]             ;Get List of Lists address
  124.                 les     di,es:[di+4]            ;Get address of SFT
  125.                 xor     al,al                   ;Zero file count
  126.  
  127. countf1:        mov     cx,es:[di+4]            ;Get count of SFT entries
  128.                 jcxz    countf4                 ;Branch if count is zero
  129.                 mov     si,di                   ;Point SI to the first SFT
  130.                 add     si,6                    ;entry in this block
  131.  
  132. countf2:        cmp     word ptr es:[si],0      ;Increment count in AL if
  133.                 je      countf3                 ;the handle count is not
  134.                 inc     al                      ;zero
  135. countf3:        add     si,59                   ;Point SI to the next entry
  136.                 loop    countf2                 ;Loop until all entries done
  137.  
  138. countf4:        cmp     word ptr es:[di],0FFFFh ;Exit if this is the last
  139.                 je      cf_exit                 ;block in the chain
  140.                 les     di,es:[di]              ;Get address of next block
  141.                 jmp     countf1                 ;Reenter the loop
  142. cf_exit:        ret
  143. count_files     endp
  144.  
  145. ;****************************************************************************
  146. ; Data that will be discarded when the program becomes memory-resident.
  147. ;****************************************************************************
  148.  
  149. helpmsg         db      "Tracks file activity as an aid in determining the "
  150.                 db      "optimum setting for the",13,10
  151.                 db      "FILES= statement in CONFIG.SYS.",13,10,"$"
  152.  
  153. errmsg1         db      "Requires DOS 5 or DOS 6",13,10,"$"
  154. errmsg2         db      "Program could not be installed"
  155. crlf            db      13,10,"$"
  156.  
  157. copyright       db      "FILEMON 1.1 Copyright (c) 1993 Jeff Prosise",13,10
  158.                 db      "From: PC Magazine DOS 6 Memory Management "
  159.                 db      "with Utilities",13,10,13,10,"$"
  160.  
  161. msg1            db      "Program installed. Type FILEMON to determine the "
  162.                 db      "number of open files.",13,10,"$"
  163. msg2            db      "Files currently open: $"
  164. msg3            db      "Maximum thus far:     $"
  165.  
  166. ;****************************************************************************
  167. ; INIT makes the program resident in memory.
  168. ;****************************************************************************
  169.  
  170.                 assume  cs:code,ds:code
  171.  
  172. init            proc    near
  173.                 cld                             ;Clear direction flag
  174.                 mov     si,81h                  ;Point SI to command line
  175.                 call    scanhelp                ;Scan for "/?" switch
  176.                 jnc     init1                   ;Branch if not found
  177.                 mov     ah,09h                  ;Display help text and exit
  178.                 mov     dx,offset helpmsg       ;with ERRORLEVEL=0
  179.                 int     21h
  180.                 mov     ax,4C00h
  181.                 int     21h
  182. ;
  183. ; Check the DOS version.
  184. ;
  185. init1:          mov     dx,offset errmsg1       ;Error if DOS version
  186.                 mov     ah,30h                  ;is not 5 or 6
  187.                 int     21h
  188.                 cmp     al,5
  189.                 je      init2
  190.                 cmp     al,6
  191.                 je      init2
  192.  
  193. error:          mov     ah,09h                  ;Display error message and
  194.                 int     21h                     ;exit with ERRORLEVEL=1
  195.                 mov     ax,4C01h
  196.                 int     21h
  197. ;
  198. ; Display file status is program is already installed.
  199. ;
  200. init2:          call    check_install           ;Branch if the program is
  201.                 jnc     install                 ;not installed
  202.  
  203.                 push    ax
  204.                 mov     ah,09h                  ;Display copyright message
  205.                 mov     dx,offset copyright
  206.                 int     21h
  207.                 pop     ax
  208.  
  209.                 mov     al,01h                  ;Get file statistics
  210.                 int     2Fh
  211.                 mov     bx,ax                   ;Transfer the result to BX
  212.  
  213.                 mov     ah,09h                  ;Display the number of files
  214.                 mov     dx,offset msg2          ;currently open
  215.                 int     21h
  216.                 mov     al,bl
  217.                 xor     ah,ah
  218.                 call    bin2asc
  219.  
  220.                 mov     ah,09h                  ;Display the maximum file
  221.                 mov     dx,offset msg3          ;count
  222.                 int     21h
  223.                 mov     al,bh
  224.                 xor     ah,ah
  225.                 call    bin2asc
  226.  
  227.                 mov     ax,4C00h                ;Exit with ERRORLEVEL=0
  228.                 int     21h
  229. ;
  230. ; Install the program.
  231. ;
  232. install:        call    mplex_id                ;Find a multiplex ID number
  233.                 mov     dx,offset errmsg2       ;Error if none available
  234.                 jc      error
  235.                 mov     prog_id,ah              ;Save the ID number
  236.  
  237.                 mov     ax,3521h                ;Hook interrupt 21H
  238.                 int     21h
  239.                 mov     word ptr int21h,bx
  240.                 mov     word ptr int21h[2],es
  241.                 mov     ax,2521h
  242.                 mov     dx,offset dos_int
  243.                 int     21h
  244.  
  245.                 mov     ax,352Fh                ;Hook interrupt 2FH
  246.                 int     21h
  247.                 mov     word ptr int2Fh,bx
  248.                 mov     word ptr int2Fh[2],es
  249.                 mov     ax,252Fh
  250.                 mov     dx,offset mplex_int
  251.                 int     21h
  252.  
  253.                 mov     ah,49h                  ;Free the local block
  254.                 mov     es,ds:[2Ch]             ;environment block
  255.                 int     21h
  256.  
  257.                 mov     ah,52h                  ;Get and save the address
  258.                 int     21h                     ;of the List of Lists
  259.                 mov     word ptr lol,bx
  260.                 mov     word ptr lol[2],es
  261.  
  262.                 mov     ah,09h                  ;Display message verifying
  263.                 mov     dx,offset copyright     ;the installation
  264.                 int     21h
  265.                 mov     ah,09h
  266.                 mov     dx,offset msg1
  267.                 int     21h
  268.  
  269.                 mov     ax,3100h                ;Terminate with function 31H
  270.                 mov     dx,(offset helpmsg - offset code + 15) shr 4
  271.                 int     21h
  272. init            endp
  273.  
  274. ;****************************************************************************
  275. ; SCANHELP scans the command line for a /? switch. If found, carry returns
  276. ; set and SI contains its offset. If not found, carry returns clear.
  277. ;****************************************************************************
  278.  
  279. scanhelp        proc    near
  280.                 push    si                      ;Save SI
  281. scanloop:       lodsb                           ;Get a character
  282.                 cmp     al,0Dh                  ;Exit if end of line
  283.                 je      scan_exit
  284.                 cmp     al,"?"                  ;Loop if not "?"
  285.                 jne     scanloop
  286.                 cmp     byte ptr [si-2],"/"     ;Loop if not "/"
  287.                 jne     scanloop
  288.  
  289.                 add     sp,2                    ;Clear the stack
  290.                 sub     si,2                    ;Adjust SI
  291.                 stc                             ;Set carry and exit
  292.                 ret
  293.  
  294. scan_exit:      pop     si                      ;Restore SI
  295.                 clc                             ;Clear carry and exit
  296.                 ret
  297. scanhelp        endp
  298.  
  299. ;****************************************************************************
  300. ; CHECK_INSTALL returns carry set if the program is already installed,
  301. ; carry clear if it's not. If carry returns set, AH holds the program's
  302. ; multiplex ID number.
  303. ;****************************************************************************
  304.  
  305. check_install   proc    near
  306.                 mov     ax,0C000h               ;Initialize AH and AL
  307.                 mov     cx,40h                  ;Initialize count
  308.  
  309. chinst1:        push    ax                      ;Save AX and CX
  310.                 push    cx
  311.                 sub     di,di                   ;Set ES and DI to 0
  312.                 mov     es,di
  313.                 int     2Fh                     ;Interrupt 2Fh
  314.                 cmp     al,0FFh                 ;Nothing here if AL isn't
  315.                 jne     chinst2                 ;equal to FFH
  316.  
  317.                 mov     si,offset signature     ;See if program signature
  318.                 mov     cx,13                   ;appears at the address
  319.                 repe    cmpsb                   ;returned in ES:DI
  320.                 jne     chinst2                 ;Branch if it does not
  321.  
  322.                 pop     cx                      ;Clear the stack and exit
  323.                 pop     ax                      ;with carry set
  324.                 stc
  325.                 ret
  326.  
  327. chinst2:        pop     cx                      ;Retrieve AX and CX
  328.                 pop     ax
  329.                 inc     ah                      ;Next multiplex ID
  330.                 loop    chinst1                 ;Loop until done
  331.  
  332.                 clc                             ;Exit with carry clear
  333.                 ret
  334. check_install   endp
  335.  
  336. ;****************************************************************************
  337. ; MPLEX_ID searches for an unused multiplex ID number. If one is found,
  338. ; it is returned in AH with carry clear. Carry set means no multiplex
  339. ; ID numbers are currently available.
  340. ;****************************************************************************
  341.  
  342. mplex_id        proc    near
  343.                 mov     ax,0C000h               ;Initialize AH and AL
  344.                 mov     cx,40h                  ;Initialize count
  345.  
  346. mxid1:          push    ax                      ;Save AX and CX
  347.                 push    cx
  348.                 int     2Fh                     ;Interrupt 2Fh
  349.                 or      al,al                   ;Branch if AL=0
  350.                 jz      mxid2
  351.                 pop     cx                      ;Retrieve AX and CX
  352.                 pop     ax
  353.                 inc     ah                      ;Increment ID number
  354.                 loop    mxid1                   ;Loop until done
  355.  
  356.                 stc                             ;Exit with carry set
  357.                 ret
  358.  
  359. mxid2:          pop     cx                      ;Clear the stack and exit
  360.                 pop     ax                      ;with carry clear
  361.                 clc
  362.                 ret
  363. mplex_id        endp
  364.  
  365. ;****************************************************************************
  366. ; BIN2ASC converts a binary value in AX to ASCII form and displays it.
  367. ;****************************************************************************
  368.  
  369. ten             dw      10                      ;Base 10 divisor
  370.  
  371. bin2asc         proc    near
  372.                 xor     cx,cx                   ;Initialize digit counter
  373. b2a1:           inc     cx                      ;Increment digit count
  374.                 xor     dx,dx                   ;Divide by 10
  375.                 div     ten
  376.                 push    dx                      ;Save remainder on stack
  377.                 or      ax,ax                   ;Loop until quotient is zero
  378.                 jnz     b2a1
  379. b2a2:           pop     dx                      ;Retrieve a digit from stack
  380.                 add     dl,30h                  ;Convert it to ASCII
  381.                 mov     ah,2                    ;Display it
  382.                 int     21h
  383.                 loop    b2a2                    ;Loop until done
  384.                 mov     ah,09h                  ;Move the cursor to the
  385.                 mov     dx,offset crlf          ;next line
  386.                 int     21h
  387.                 ret
  388. bin2asc         endp
  389.  
  390. code            ends
  391.                 end     begin
  392.